package main

/*
#cgo CFLAGS: --sysroot /Users/xinchen/android-sdk-macosx/ndk/toolchain/sysroot -I/Users/xinchen/android-sdk-macosx/ndk/21.0.6113669/sysroot/usr/include/arm-linux-androideabi -I/Users/xinchen/android-sdk-macosx/ndk/toolchain/sysroot/usr/include
#cgo LDFLAGS: -landroid -llog
#include <jni.h>
#include <android/log.h>
#define LOG_INFO(...) __android_log_print(ANDROID_LOG_INFO, "Go", __VA_ARGS__)
#define LOG_FATAL(...) __android_log_print(ANDROID_LOG_FATAL, "Go", __VA_ARGS__)
*/
import "C"
import (
	"fmt"
	"log"
	"net/http"
	"net/url"
	"path"
	"strconv"
	"strings"
	"time"

	LRUCache "github.com/hashicorp/golang-lru"
	"github.com/mr-tron/base58"
)

type Handlers struct {
	w http.ResponseWriter
	r *http.Request
}

var lrucache *LRUCache.Cache
var (
	eport       int    = 16677
	networkType string = "ct1" //中国电信
	cachecount  int    = 20000
)
var DATABASE *DB

const (
	InfoColor    = "\033[1;34m%s\033[0m \n"
	NoticeColor  = "\033[1;36m%s\033[0m \n"
	WarningColor = "\033[1;33m%s\033[0m \n"
	ErrorColor   = "\033[1;31m%s\033[0m \n"
	DebugColor   = "\033[0;36m%s\033[0m \n"
	ProxyRouter  = "proxy"
)

/*代理http函数*/
func (server Handlers) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	var method = r.Method
	server.w = w
	server.r = r
	switch method {
	case "GET":
		server.Handle() //处理get方式
	default:
		w.WriteHeader(500)
	}
}

func (server Handlers) Handle() {
	urlpath := server.r.URL.Path
	base58url := urlpath[1:]
	var isProxyRouter bool
	var fname string
	var chk string
	p := strings.Split(base58url, "/")
	if len(p) == 2 && p[0] == ProxyRouter {
		isProxyRouter = true
		ext := path.Ext(p[1])
		b58url := strings.TrimSuffix(p[1], ext)
		c, err := base58.Decode(b58url)
		if err != nil {
			fmt.Printf("Demo %v, got error %s\n", c, err)
			server.w.WriteHeader(500)
			return
		}
		bs58c := path.Base(string(c))
		cc, errs := base58.Decode(bs58c)
		if errs != nil {
			fmt.Printf("Demo %v, got error %s\n", cc, err)
			server.w.WriteHeader(500)
			return
		}
		uu, _ := url.Parse(string(cc))
		fname = strings.TrimSuffix(uu.Path, ext)
		chk = string(c) + ext
		fmt.Println("chk is:::::", chk)
	} else {
		isProxyRouter = false
		base58url = strings.Split(base58url, ".")[0]

		num, err := base58.Decode(base58url)
		if err != nil {
			fmt.Printf("Demo %v, got error %s\n", base58url, err)
			server.w.WriteHeader(500)
			return
		}
		chk = string(num)
	}
	var chkpath string
	u, err := url.Parse(chk)
	if err == nil {
		chkpath = u.Path
	} else {
		fmt.Printf("Demo %v, got error %s\n", base58url, err)
		server.w.WriteHeader(500)
		return
	}
	if strings.HasPrefix(chk, "http") == false {
		fmt.Printf("error url sechma %s\n", chk)
		server.w.WriteHeader(500)
		return
	}
	// chk := base58.Encode(num)
	if strings.HasSuffix(chkpath, ".mp4") {
		h := NewRangeHandle(server.w, server.r, chk, isProxyRouter, fname)
		h.Handle()
	} else if strings.HasSuffix(chkpath, ".ts") {
		if strings.Contains(u.Host, "xnxx-cdn") == true {
			h := NewBlockHandle(server.w, server.r, chk)
			h.Handle()
		} else {
			h := NewTSHandle(server.w, server.r, chk)
			h.Handle()
		}

	} else if strings.HasSuffix(chkpath, ".m3u8") {
		h := NewM3U8Handle(server.w, server.r, chk)
		h.Handle()
	} else {
		h := NewBlockHandle(server.w, server.r, chk)
		h.Handle()
	}
}

//export Java_org_golang_example_bind_MainActivity_run
func Java_org_golang_example_bind_MainActivity_run(env *C.JNIEnv, clazz C.jclass) {
	run()
}

func run() {
	MakeCacheDir()
	go SetUPnP()
	go jobs()
	lrucache, _ = LRUCache.New(200)
	RangeInit()
	DATABASE = InitDB()
	var server Handlers
	http.Handle("/", server)
	err := http.ListenAndServe(":"+strconv.Itoa(eport), nil)
	if err != nil {
		fmt.Println(err)
	}
}
func jobs() {
	mac := GetMACAddress()
	log.Printf(mac)
	ID := SHA1(mac)
	clearTicker := time.NewTicker(5 * time.Minute)
	pingTicker := time.NewTicker(1000 * time.Minute)
	for {
		select {
		case <-clearTicker.C:
			ClearCache()
		case <-pingTicker.C:
			Ping(ID)
		}
	}
}
func main() {
}
